package com.heima.xiyuanmall.sudoku

import android.os.Handler
import android.os.Message

/**
 * @author flutterdash@qq.com
 * @since 2021/10/2 21:38
 */
object SudokuAutoSolver : Thread() {

    private lateinit var handler: Handler
    private lateinit var board: Board

    /**
     * 注入 handler
     *
     * 随界面初始化时调用
     */
    fun init(handler: Handler) {
        this.handler = handler
        board = defaultTestBoard()
        SCache.init(board)
    }

    override fun run() = solveDelegate()

    private fun solveDelegate() =
        if (solve()) success()
        else failure()

    fun solve(pos: Pos = Pos()): Boolean {
        sleep(1)

        if (pos.finished) return true

        if (board[pos.row][pos.col] == 0) {
            for (num in 1..side) {
                if (SCache.canUse(pos, num)) {
                    SCache.makeMark(pos, num)

                    onSelected(pos)
                    onTransfer(pos)

                    if (solve(pos.next()))
                        return true

                    SCache.removeMark(pos, num)
                    onUncheck(pos)
                }
            }
        } else {
            return solve(pos.next())
        }

        return false
    }

    private fun onSelected(pos: Pos) = RenderEventEmitter.selectedEvent(pos).send()
    private fun onTransfer(pos: Pos) = RenderEventEmitter.transferEvent(pos).send()
    private fun onUncheck(pos: Pos) = RenderEventEmitter.uncheckEvent(pos).send()

    private fun success() = Unit
    private fun failure() = Unit

    private fun RenderEventsHolder.send() =
        this@SudokuAutoSolver.sendMessageToUpdateView(this)

    private fun sendMessageToUpdateView(events: EventsHolder) {
        handler.sendMessage(Message().apply {
            obj = events
        })
    }

    @Deprecated("下个版本删除这个方法")
    private fun refresh() =
        handler.sendMessage(Message().apply {
            obj = SCache.showAnswer()
        })
}